package bridge

import (
	"fmt"
	"os"

	"cloudea.com/container/config"
	"cloudea.com/container/utils"
	"github.com/vishvananda/netlink"
)

/** 保证container0网桥存在 */
func EnsureContainer0() error {
	/**
		bridge 是临时设备，经实验重启就没了
	**/
	bridge, _ := netlink.LinkByName(config.CONTAINER0)

	if bridge == nil || bridge.Type() != "bridge" {
		linkAttr := netlink.NewLinkAttrs()
		linkAttr.Name = config.CONTAINER0
		bridge = &netlink.Bridge{
			LinkAttrs: linkAttr,
		}
		// 添加
		err := netlink.LinkAdd(bridge)
		if err != nil {
			return err
		}

		// 设置IP地址
		netIP, mask := utils.IPCIDRParse(config.CONTAINER0_CIDR)
		addr, _ := netlink.ParseAddr(utils.IPCIDREncode(netIP+1, mask))
		err = netlink.AddrAdd(bridge, addr)
		if err != nil {
			return err
		}
	}

	// 设置NS
	netFile, _ := os.Open("/proc/self/ns/net")
	netlink.LinkSetNsFd(bridge, int(netFile.Fd()))

	// 启动
	return netlink.LinkSetUp(bridge)
}

/** 保证container0网桥存在 */
func RemoveContainer0() error {
	bridge, _ := netlink.LinkByName(config.CONTAINER0)
	if bridge != nil {
		return netlink.LinkDel(bridge)
	}
	return nil
}

/** 保证可以连接互联网 */
func EnsureInternet() error {
	// 设置Master以连接互联网（经测试：有时候能连，有时候不能连，很玄学）
	links, _ := netlink.LinkList()
	for _, link := range links {
		if link.Type() == "device" && link.Attrs().Name != "lo" {
			// 使容器可以连接互联网
			utils.Assert(utils.Shell("sysctl net.ipv4.conf.all.forwarding=1"))
			utils.Assert(utils.Shell("iptables -P FORWARD ACCEPT"))
			// Assert(Shell(fmt.Sprintf("iptables -t nat -A POSTROUTING -o %s -j MASQUERADE", config.CONTAINER0)))
			// Assert(Shell(fmt.Sprintf("iptables -t nat -A POSTROUTING -o %s -j MASQUERADE", link.Attrs().Name)))
			utils.Assert(utils.Shell(fmt.Sprintf("iptables -t nat -A POSTROUTING -s %s -o %s -j MASQUERADE", config.CONTAINER0_CIDR, link.Attrs().Name)))
			break
		}
	}
	return nil
}
